package com.baijiayun.live.ui.pptpanel

import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.util.AttributeSet
import android.view.ViewGroup
import com.baijiayun.live.ui.R
import com.baijiayun.live.ui.activity.LiveRoomBaseActivity
import com.baijiayun.live.ui.base.RouterViewModel
import com.baijiayun.live.ui.removeSwitchableFromParent
import com.baijiayun.live.ui.speakerlist.item.SpeakItemType
import com.baijiayun.live.ui.speakerlist.item.Switchable
import com.baijiayun.live.ui.speakerlist.item.SwitchableStatus
import com.baijiayun.live.ui.speakerlist.item.SwitchableType
import com.baijiayun.livecore.context.LPConstants
import com.baijiayun.livecore.models.animppt.LPAnimPPTPageChangeEndModel
import com.baijiayun.livecore.ppt.PPTView
import com.baijiayun.livecore.ppt.photoview.OnDoubleTapListener
import com.baijiayun.livecore.ppt.whiteboard.shape.Shape
import com.baijiayun.livecore.ppt.whiteboard.shape.TextShape
import com.baijiayun.liveuibase.utils.ThemeDataUtil
import com.baijiayun.liveuibase.widgets.dialog.ThemeMaterialDialogBuilder
import java.util.*

/**
 * Created by Shubo on 2019-10-15.
 */
@SuppressLint("ViewConstructor")
class MyPadPPTView(context: Context, val routerViewModel: RouterViewModel, attr: AttributeSet? = null) : PPTView(context, attr), Switchable {
    var pptStatus = SwitchableStatus.MaxScreen
    var closeByExtCamera = false //和辅助摄像头互斥
    private var isInFullScreen = false

    override fun isInFullScreen() = this.isInFullScreen

    override fun getPositionInParent(): Int {
        val viewParent = view.parent ?: return -1
        return (viewParent as ViewGroup).indexOfChild(view)
    }

    override fun getIdentity() = "PPT"

    //ppt替换掉辅助摄像头
    override fun syncPPTExtCamera(closeItem: Switchable) {
        if (closeItem.isInFullScreen) {
            when (closeItem.switchableStatus) {
                SwitchableStatus.MainVideo -> switchToMainScreen()
                SwitchableStatus.MaxScreen -> switchToMaxScreen()
                else -> switchToSpeakList()
            }
            switchToFullScreen(true)
        } else {
            //替换closeItem位置
            when (closeItem.switchableStatus) {
                SwitchableStatus.MainVideo -> switchToMainScreen()
                SwitchableStatus.MaxScreen -> switchToMaxScreen()
                else -> switchToSpeakList()
            }
        }
    }

    override fun getItemType() = SpeakItemType.PPT

    override fun getView() = this
    override fun replaceVideoSync(switchable: Switchable?) {
        if (switchable == null) {
            return
        }
        if (switchable === this) {
            when (switchable.switchableStatus) {
                SwitchableStatus.MainVideo -> switchToMainScreen()
                SwitchableStatus.MaxScreen -> switchToMaxScreen()
                SwitchableStatus.SpeakList -> switchToSpeakList()
            }
            return
        }
        val currentStatus: SwitchableStatus = pptStatus
        when (switchable.switchableStatus) {
            SwitchableStatus.MainVideo -> switchToMainScreen()
            SwitchableStatus.MaxScreen -> switchToMaxScreen()
            SwitchableStatus.SpeakList -> switchToSpeakList()
        }
        when (currentStatus) {
            SwitchableStatus.MainVideo -> switchable.switchToMainScreen()
            SwitchableStatus.SpeakList -> switchable.switchToSpeakList()
            SwitchableStatus.MaxScreen -> switchable.switchToMaxScreen()
        }
    }

    override fun getSwitchableStatus(): SwitchableStatus = if (closeByExtCamera) {
        routerViewModel.extCameraData.value?.second?.switchableStatus ?: pptStatus
    } else {
        pptStatus
    }


    override fun switchToFullScreen(isFullScreen: Boolean) {
        this.isInFullScreen = isFullScreen
        removeSwitchableFromParent(this)
        routerViewModel.switch2FullScreen.value = isFullScreen to this
    }

    override fun switchToMaxScreen() {
        if (closeByExtCamera) {
            switchExtCameraToMaxScreen()
        } else {
            removeSwitchableFromParent(this)
            routerViewModel.switch2MaxScreen.value = this
            pptStatus = SwitchableStatus.MaxScreen
        }
    }

    override fun switchToMainScreen() {
        if (closeByExtCamera) {
            switchExtCameraToMainScreen()
            return
        }
        removeSwitchableFromParent(this)
        routerViewModel.closeDrawingMode.value = Unit
        routerViewModel.switch2MainVideo.value = this
        pptStatus = SwitchableStatus.MainVideo
    }

    override fun switchToSpeakList() {
        if (closeByExtCamera) {
            switchExtCameraToSpeakList()
            return
        }
        removeSwitchableFromParent(this)
        routerViewModel.closeDrawingMode.value = Unit
        routerViewModel.switch2SpeakList.value = this
        pptStatus = SwitchableStatus.SpeakList
    }


    override fun setSwitchableStatus(status: SwitchableStatus) {
        this.pptStatus = status
    }

    override fun switchPPTVideoSync() = with(routerViewModel) {
        if (liveRoom.isSyncPPTVideo && (liveRoom.isTeacherOrAssistant || liveRoom.isGroupTeacherOrAssistant)
            && isMainVideo() && liveRoom.isClassStarted) {
            showSwitchDialog()
        } else {
            switch2MaxScreenLocal()
        }
    }
    private fun canSwitchPPTAndMainVideo(): Boolean {
        return !routerViewModel.isLiveWall()
    }
    override fun switchPPTVideoWithoutSync(immediately: Boolean) {
        routerViewModel.switch2MaxScreen.value?.run {
            if (switchableType == SwitchableType.MainItem) {
                if (!isInFullScreen || immediately) {
                    if (isInFullScreen) {
                        switchToFullScreen(false)
                    }
                    switchToMainScreen()
                } else {
                    switchableStatus = SwitchableStatus.MainVideo
                }
            } else if (switchableType == SwitchableType.SpeakItem) {
                if (!isInFullScreen || immediately) {
                    if (isInFullScreen) {
                        switchToFullScreen(false)
                    }
                    switchToSpeakList()
                } else {
                    switchableStatus = SwitchableStatus.SpeakList
                }
            }
        }
        if (!isInFullScreen || immediately) {
            if (isInFullScreen) {
                switchToFullScreen(false)
            }
            switchToMaxScreen()
        } else {
            switchableStatus = SwitchableStatus.MaxScreen
        }
    }

    override fun isPlaceholderItem() = false

    private fun switchExtCameraToMaxScreen() {
        routerViewModel.extCameraData.value?.second?.let {
            removeSwitchableFromParent(it)
            routerViewModel.switch2MaxScreen.value = it
        }
    }

    private fun switchExtCameraToSpeakList() {
        routerViewModel.extCameraData.value?.second?.let {
            removeSwitchableFromParent(it)
            routerViewModel.switch2SpeakList.value = it
        }
    }

    private fun switchExtCameraToMainScreen() {
        routerViewModel.extCameraData.value?.second?.let {
            removeSwitchableFromParent(it)
            routerViewModel.switch2MainVideo.value = it
        }
    }

    override fun getSwitchableType() = SwitchableType.PPT

    fun closePPTbyExtCamera() {
        removeSwitchableFromParent(this)
        closeByExtCamera = true
    }

    fun start() {
        mPageTv.setOnClickListener {
            if (switchableStatus == SwitchableStatus.MaxScreen || isInFullScreen) {
                if (isEditable) {
                    routerViewModel.closeDrawingMode.value = Unit
                }
                routerViewModel.actionShowQuickSwitchPPT.value = Bundle().apply {
                    putInt("currentIndex", currentPageIndex)
                    putInt("maxIndex", maxPage)
                }
            }
        }
        super.setOnViewTapListener { _, _, _ ->
            if (switchableStatus != SwitchableStatus.MaxScreen && !isInFullScreen) {
                showOptionDialog()
                return@setOnViewTapListener
            }
        }
        super.setOnDoubleTapListener(object : OnDoubleTapListener {

            override fun onDoubleTapConfirmed() {
                if (switchableStatus == SwitchableStatus.MaxScreen || isInFullScreen) {
                    setDoubleTapScaleEnable(true)
                } else {
                    setDoubleTapScaleEnable(false)
                    switchPPTVideoSync()
                }
            }


            override fun onDoubleTapOnShape(shape: Shape?) {
                routerViewModel.editTextShape.value = (shape as TextShape).text
            }
        })
        super.setPPTErrorListener(object : OnPPTErrorListener {
            override fun onAnimPPTLoadStart() {
                // do nothing
            }

            override fun onAnimPPTLoadError(errorCode: Int, description: String?) {
                if (!closeByExtCamera) {
                    routerViewModel.action2PPTError.value = errorCode to description
                }
            }

            override fun onAnimPPTLoadFinish() {
                routerViewModel.action2PPTError.value = LPConstants.ON_PPT_LOAD_FINISH_CODE to ""
            }
        })

        setPPTStatusListener(object : PPTStatusListener {
            override fun onPageChange(pageChangeEndModel: LPAnimPPTPageChangeEndModel?, remarkInfo: String?) {
                // do nothing
            }

            override fun onH5PageCountChange(docId: String?, page: Int) {
                // do nothing
            }

            override fun onPPTViewAttached() {
                setAnimPPTAuth(true)
            }
        })
    }

    override fun getPPTBgColor(): Int = ThemeDataUtil.getColorFromThemeConfigByAttrId(context, R.attr.base_theme_room_bg_color)

    private fun showOptionDialog() {
        if (context == null) return
        val options: MutableList<String> = ArrayList()
        if (!isInFullScreen) {
            if (routerViewModel.canOperateH5PPT()) {
                if (!routerViewModel.liveRoom.hasH5PPTAuth()) {
                    options.add(context.getString(R.string.live_h5_ppt_auth))
                }else{
                    options.add(context.getString(R.string.live_h5_ppt_auth_cancel))
                }
            }
            options.add(context.getString(R.string.live_full_screen))
            if (canSwitchPPTAndMainVideo()) {
                options.add(context.getString(R.string.live_max_screen))
            }
        } else {
            options.add(context.getString(R.string.live_full_screen_exit))
        }
        ThemeMaterialDialogBuilder(context)
                .items(options)
                .itemsCallback { materialDialog, _, _, charSequence ->
                    if (context == null) {
                        return@itemsCallback
                    }
                    when (charSequence.toString()) {
                        context.getString(R.string.live_max_screen) -> switchPPTVideoSync()
                        context.getString(R.string.live_full_screen) -> switchToFullScreen(true)
                        context.getString(R.string.live_full_screen_exit) -> switchToFullScreen(false)
                        context.getString(R.string.live_h5_ppt_auth) -> routerViewModel.liveRoom.requestH5PPTAuth(true)
                        context.getString(R.string.live_h5_ppt_auth_cancel) -> showH5PPTAuthDialog(false)
                    }
                    materialDialog.dismiss()
                }
                .show()
    }

    fun showH5PPTAuthDialog(auth: Boolean) {
        ThemeMaterialDialogBuilder(context)
                .apply {
                    title(context.getString(R.string.live_h5_ppt_auth_cancel_title))
                    content(context.getString(R.string.live_h5_ppt_auth_cancel_content))
                }
                .apply {
                    positiveText(context.getString(R.string.live_ppt_auth_cancel))
                    positiveColorRes(R.color.base_warning_color)
                    onPositive { dialog, _ ->
                        run {
                            routerViewModel.liveRoom.requestH5PPTAuth(auth)
                            dialog.dismiss()
                        }
                    }
                }
                .apply {
                    negativeText(context.getString(R.string.live_ppt_auth_confirm))
                    onNegative { dialog, _ -> dialog.dismiss() }
                }
                .show()
    }

    private fun isMainVideo() = pptStatus == SwitchableStatus.MainVideo

    fun switch2MaxScreenLocal() {
        routerViewModel.switch2MaxScreen.value?.run {
            if (switchableType == SwitchableType.MainItem) {
                switchToMainScreen()
            } else if (switchableType == SwitchableType.SpeakItem) {
                switchToSpeakList()
            }
        }
        switchToMaxScreen()
    }

    private fun switch2MaxScreenSync() {
        routerViewModel.liveRoom.requestPPTVideoSwitch(false)
        switch2MaxScreenLocal()
    }

    private fun showSwitchDialog() {
        if (context == null || context !is LiveRoomBaseActivity) {
            return
        }
        val cxt = context as LiveRoomBaseActivity
        if (cxt.isFinishing || cxt.isDestroyed) {
            return
        }
        context.let {
            ThemeMaterialDialogBuilder(it)
                    .title(it.getString(R.string.live_exit_hint_title))
                    .content(it.getString(R.string.live_pad_sync_video_ppt))
                    .positiveText(R.string.live_pad_switch_sync)
                    .negativeText(R.string.live_pad_switch_local)
                    .negativeColor(ThemeDataUtil.getColorFromThemeConfigByAttrId(it, R.attr.base_theme_dialog_negative_text_color))
                    .onPositive { _, _ -> switch2MaxScreenSync() }
                    .onNegative { _, _ -> switch2MaxScreenLocal() }
                    .show()
        }
    }

    override fun setMaxPage(maxIndex: Int) {
        super.setMaxPage(maxIndex)
        refreshPageTagInfo(maxIndex)
        routerViewModel.actionChangePPT2Page.value = maxIndex
    }
}